{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "# `if` 语句之外的 `else` 块\n",
    "\n",
    "<code>else</code>子句不仅能在<code>if</code>语句中使用，\n",
    "还能在<code>for</code>、<code>while</code>、<code>try</code>语句中使用。\n",
    "<code>else</code>子句的行为：\n",
    "\n",
    "- **`for`:** 仅当<code>for</code>循环正常运行完毕时\n",
    "  （即<code>for</code>循环没有被<code>break</code>语句终止）才运行<code>else</code>块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "from random import randrange\n",
    "\n",
    "\n",
    "def insertion_sort(seq):\n",
    "    if len(seq) <= 1:\n",
    "        return seq\n",
    "\n",
    "    _sorted = seq[:1]\n",
    "    for i in seq[1:]:\n",
    "        inserted = False\n",
    "        for j in range(len(_sorted)):\n",
    "            if i < _sorted[j]:\n",
    "                _sorted = [*_sorted[:j], i, *_sorted[j:]]\n",
    "                inserted = True\n",
    "                break\n",
    "        if not inserted:\n",
    "            _sorted.append(i)\n",
    "    return _sorted\n",
    "\n",
    "\n",
    "print(insertion_sort([randrange(1, 100) for i in range(10)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "from random import randrange\n",
    "\n",
    "\n",
    "def insertion_sort(seq):\n",
    "    if len(seq) <= 1:\n",
    "        return seq\n",
    "\n",
    "    _sorted = seq[:1]\n",
    "    for i in seq[1:]:\n",
    "        for j in range(len(_sorted)):\n",
    "            if i < _sorted[j]:\n",
    "                _sorted = [*_sorted[:j], i, *_sorted[j:]]\n",
    "                break\n",
    "        else:\n",
    "            _sorted.append(i)\n",
    "    return _sorted\n",
    "\n",
    "\n",
    "print(insertion_sort([randrange(1, 100) for i in range(10)]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "- **`while`:** 仅当<code>while</code>循环因为条件为 **假值** 而退出时\n",
    "  （即<code>while</code>循环没有被<code>break</code>语句终止）才运行<code>else</code>语句。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "while False:\n",
    "    print('Will never print!')\n",
    "else:\n",
    "    print('Loop failed!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "- **`try`:** 仅当<code>try</code>块中没有异常抛出时才运行<code>else</code>块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "def divide(x, y):\n",
    "    try:\n",
    "        result = x / y\n",
    "    except ZeroDivisionError:\n",
    "        print(\"division by 0!\")\n",
    "    else:\n",
    "        print(\"result = {}\".format(result))\n",
    "    finally:\n",
    "        print(\"divide finished!\")\n",
    "\n",
    "\n",
    "divide(2, 1)\n",
    "print('-' * 16)\n",
    "divide(2, 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "在所有的情况下，如果异常或者<code>return</code>、<code>break</code>或\n",
    "<code>continue</code>语句导致控制权跳到了复合语句的主块之外，\n",
    "<code>else</code>语句也会被跳过。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "# 浅复制与深复制\n",
    "\n",
    "复制列表（或多数内置的可变集合）最简单的方式是使用内置的类型构造方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "l1 = [3, [55, 44], (7, 8, 9)]\n",
    "l2 = list(l1)  # l2 = l1[:]\n",
    "print(l2)\n",
    "print(l2 == l1)\n",
    "print(l2 is l1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "构造方法或<code>[:]</code>做的是 **浅复制**\n",
    "（即复制了最外层容器，副本中的元素是源容器中元素的引用）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "l1 = [3, [55, 44], (7, 8, 9)]\n",
    "l2 = list(l1)\n",
    "l1.append(100)\n",
    "l1[1].remove(55)\n",
    "print('l1:', l1)\n",
    "print('l2:', l2)\n",
    "l2[1] += [33, 22]\n",
    "l2[2] += (10, 11)\n",
    "print('l1:', l1)\n",
    "print('l2:', l2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "## 为任意对象做深复制和浅复制\n",
    "\n",
    "有时我们需要深复制（即副本不共享内部对象的引用。）\n",
    "<code>copy</code>模块提供的<code>deepcopy</code>和<code>copy</code>函数能为任意对象做深复制和浅复制。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "class Bus:\n",
    "\n",
    "    def __init__(self, passengers=None):\n",
    "        if passengers is None:\n",
    "            self.passengers = []\n",
    "        else:\n",
    "            self.passengers = list(passengers)\n",
    "\n",
    "    def pick(self, name):\n",
    "        self.passengers.append(name)\n",
    "\n",
    "    def drop(self, name):\n",
    "        self.passengers.remove(name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "autoscroll": false,
    "collapsed": false,
    "ein.hycell": false,
    "ein.tags": "worksheet-0",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "import copy\n",
    "\n",
    "bus1 = Bus(['Alice', 'Bill', 'Claire', 'David'])\n",
    "bus2 = copy.copy(bus1)\n",
    "bus3 = copy.deepcopy(bus1)\n",
    "print(id(bus1), id(bus2), id(bus3))\n",
    "bus1.drop('Bill')\n",
    "print(bus2.passengers)\n",
    "print(id(bus1.passengers), id(bus2.passengers), id(bus3.passengers))\n",
    "print(bus3.passengers)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "name": "15-else-and-copy.ipynb"
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
